package pl.nazaweb.jboot.walking;

import java.awt.Point;
import java.util.LinkedList;
import pl.nazaweb.jboot.WayDirection;

/**
 *
 * @author Marek Kawczyński
 */
public class WayFinder {

    public static int UNUSED_FIELD = -1;
    private int[][] world;
    private LinkedList<WayDirection> way = new LinkedList();
    private int[][] visitedWorld;
    private Point previousPoint;

    public WayFinder(int[][] world) {
        this.world = world;
    }

    public WayFinder() {
    }

    public LinkedList<WayDirection> findWay(Point start, Point end) {
        way = new LinkedList();
        LinkedList<Point> queue = new LinkedList();
        visitedWorld = new int[world.length][world[0].length];
        queue.add(start);
        Point currPoint = start;
        while (true) {
            int lastx = currPoint.x;
            int lasty = currPoint.y;
            currPoint = getNextPoint(currPoint);
            visitedWorld[lastx][lasty] = 1;
            previousPoint = new Point(lastx, lasty);
            System.out.println("next point x: " + currPoint.x + ", y: " + currPoint.y);
            if (currPoint.x == end.x && currPoint.y == end.y) {
                break;
            }
        }
        return way;
    }

    public void findWay2(Point start, Point end) {
        LinkedList<Point> queue = new LinkedList();
        int[][] temporaryMap = new int[1000][1000];
        initializeMap(temporaryMap);
        temporaryMap[start.x][start.y] = 1;
        queue.add(start);
        boolean wayFound = false;
        while (!queue.isEmpty() && !wayFound) {
            Point currentPoint = queue.getFirst();
            int currentPointValue = temporaryMap[currentPoint.x][currentPoint.y];
            queue.removeFirst();
            Point[] nearPoints = getNearPoints(currentPoint);
            for (int x = 0; x < 4; x++) {
                if (isPointOutOfMap(nearPoints[x])) {
                    continue;
                }
                if (temporaryMap[nearPoints[x].x][nearPoints[x].y] == UNUSED_FIELD
                        && world[nearPoints[x].x][nearPoints[x].y] != 0) {
                    temporaryMap[nearPoints[x].x][nearPoints[x].y] = currentPointValue + 1;
                    queue.addLast(new Point(nearPoints[x].x, nearPoints[x].y));
                }
                if (arePointsTheSame(nearPoints[x], end)) {
                    wayFound = true;
                    break;
                }
            }
        }
        System.out.println("znaleziono");
    }
    
    private void createWay(Point end, int[][] temporaryMap, LinkedList<Point> way){
        //Point p     
    }

    private boolean arePointsTheSame(Point first, Point second) {
        if (first.x == second.x && first.y == second.y) {
            return true;
        }
        return false;
    }

    private void initializeMap(int[][] map) {
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[0].length; j++) {
                map[i][j] = UNUSED_FIELD;
            }
        }
    }

    private boolean isPointOutOfMap(Point point) {
        if (point.x == 1000 || point.y == 1000) {
            return true;
        }
        return false;
    }

    private Point getNextPoint(Point curPoint) {
        for (Point point : getNearPoints(curPoint)) {
            if (world[point.x][point.y] == 1
                    && isPointVisited(point.x, point.y) == false) {
                return point;
            }
        }
        return previousPoint;
    }

    private Point[] getNearPoints(Point p) {
        Point[] nearPoints = new Point[4];
        nearPoints[0] = new Point(p.x, p.y + 1);
        nearPoints[1] = new Point(p.x, p.y - 1);
        nearPoints[2] = new Point(p.x + 1, p.y);
        nearPoints[3] = new Point(p.x - 1, p.y);
        return nearPoints;
    }

    private boolean isPointVisited(int x, int y) {
        return visitedWorld[x][y] == 1 ? true : false;
    }

    public int[][] getWorld() {
        return world;
    }

    public void setWorld(int[][] world) {
        this.world = world;
    }
}
